﻿using ERP_SaaS_WinForm.生产计划_派单_车间;
using ERP_SaaS_WinForm.销售.Sales;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ERP_SaaS_WinForm.销售
{
    /// <summary>
    /// 客户单价修改窗体
    /// 用于修改现有的客户单价记录，支持客户和产品的重新选择
    /// </summary>
    public partial class UpdateClientPrice : Form
    {
        #region 属性定义

        /// <summary>
        /// 客户单价ID - 要修改的记录ID
        /// </summary>
        public int ClientPriceId { get; set; }
        
        /// <summary>
        /// 客户单价编号 - 客户单价的唯一编号
        /// </summary>
        public string ClientPriceCode { get; set; }
        
        /// <summary>
        /// 客户ID - 关联的客户ID
        /// </summary>
        public int ClientId { get; set; }
        
        /// <summary>
        /// 客户名称 - 关联的客户名称
        /// </summary>
        public string ClientName { get; set; }
        
        /// <summary>
        /// 产品编码 - 关联的产品编码
        /// </summary>
        public string ProductCode { get; set; }
        
        /// <summary>
        /// 产品名称 - 关联的产品名称
        /// </summary>
        public string ProductName { get; set; }
        
        /// <summary>
        /// 产品规格型号 - 产品的规格型号信息
        /// </summary>
        public string Specification { get; set; }
        
        /// <summary>
        /// 产品单价 - 产品的单价
        /// </summary>
        public string Price { get; set; }
        
        /// <summary>
        /// 产品数量 - 产品的数量
        /// </summary>
        public string Quantity { get; set; }
        
        /// <summary>
        /// 总金额 - 订单的总金额
        /// </summary>
        public string TotalAmount { get; set; }
        
        /// <summary>
        /// 备注信息 - 客户单价的备注
        /// </summary>
        public string Remark { get; set; }

        #endregion

        #region 字段定义

        /// <summary>
        /// HTTP客户端 - 用于API调用
        /// </summary>
        private HttpClient httpClient;
        
        /// <summary>
        /// API基础地址 - 客户单价更新接口
        /// </summary>
        private const string baseUrl = "http://10.223.8.6:3530/api/ClientPrice/UpdateClientPrice";

        #endregion

        /// <summary>
        /// 默认构造函数 - 初始化客户单价修改窗体
        /// </summary>
        public UpdateClientPrice()
        {
            InitializeComponent();
            // 初始化 HttpClient，避免空引用
            httpClient = new HttpClient();
        }

        /// <summary>
        /// 根据客户名称查询 ClientId（用于从旧数据回填时补齐ID）
        /// 当只有客户名称而没有客户ID时，通过API查询获取客户ID
        /// </summary>
        /// <param name="clientName">客户名称</param>
        /// <returns>客户ID，如果未找到则返回0</returns>
        private async Task<int> GetClientIdByNameAsync(string clientName)
        {
            try
            {
                string baseUrl = "http://10.223.8.6:3530/api/Client/GetClient";
                string url = string.IsNullOrWhiteSpace(clientName) ? baseUrl : $"{baseUrl}?clientName={Uri.EscapeDataString(clientName)}";
                using (HttpClient http = new HttpClient())
                {
                    HttpResponseMessage resp = await http.GetAsync(url);
                    if (!resp.IsSuccessStatusCode)
                    {
                        return 0;
                    }
                    string json = await resp.Content.ReadAsStringAsync();
                    var api = Newtonsoft.Json.JsonConvert.DeserializeObject<ERP_SaaS_WinForm.销售.Sales.SaleApiResponse>(json);
                    var match = api?.data?.FirstOrDefault(x => string.Equals(x.ClientName, clientName, StringComparison.OrdinalIgnoreCase));
                    return match?.ClientId ?? 0;
                }
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 带参数的构造函数，用于接收要修改的数据
        /// </summary>
        /// <param name="clientPriceId">客户单价ID</param>
        /// <param name="clientPriceCode">客户单价编号</param>
        /// <param name="clientName">客户名称</param>
        /// <param name="productCode">产品编码</param>
        /// <param name="productName">产品名称</param>
        /// <param name="specification">规格型号</param>
        /// <param name="price">单价</param>
        /// <param name="quantity">数量</param>
        /// <param name="totalAmount">总金额</param>
        /// <param name="remark">备注</param>
        public UpdateClientPrice(int clientPriceId, string clientPriceCode, string clientName, string productCode, 
            string productName, string specification, string price, string quantity, 
            string totalAmount, string remark)
        {
            InitializeComponent();
            
            // 保存传入的数据
            ClientPriceId = clientPriceId;
            ClientPriceCode = clientPriceCode;
            ClientName = clientName;
            ProductCode = productCode;
            ProductName = productName;
            Specification = specification;
            Price = price;
            Quantity = quantity;
            TotalAmount = totalAmount;
            Remark = remark;
            
            // 在窗体加载完成后进行数据绑定
            this.Load += UpdateClientPrice_Load;
            
            // 为修改按钮添加点击事件
            btnUpdateClientPrice.Click += btnUpdateClientPrice_Click;
            
            // 为客户选择按钮添加点击事件
            btnSelectClient.Click += BtnSelectClient_Click;
            
            // 为产品选择按钮添加点击事件
            btnSelectProduct.Click += BtnSelectProduct_Click;

            // 初始化 HttpClient，避免空引用
            httpClient = new HttpClient();
        }

        /// <summary>
        /// 窗体加载事件，用于数据反填
        /// 将传入的数据填充到界面控件中
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private async void UpdateClientPrice_Load(object sender, EventArgs e)
        {
            try
            {
                // 初始化客户信息显示标签
                InitializeClientInfoLabel();
                
                // 将数据绑定到对应的控件，确保每个字段都正确反填
                FillFormData();
                
                // 为数量变化添加事件处理，自动计算总金额
                txtProductQuantity.TextChanged += TxtProductQuantity_TextChanged;
                txtProductPrice.TextChanged += TxtProductPrice_TextChanged;
                
                // 为客户名称变化添加事件处理
                txtClient.TextChanged += TxtClient_TextChanged;
                
                // 验证反填后的数据完整性
                ValidateFilledData();
                
                // 如果已有客户名称但没有 ClientId，则根据名称查询并缓存 ClientId
                await LoadClientIdIfNeeded();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"数据反填时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 初始化客户信息显示标签
        /// </summary>
        private void InitializeClientInfoLabel()
        {
            if (!string.IsNullOrEmpty(ClientName))
            {
                lblClientInfo.Text = $"当前客户：{ClientName}";
                lblClientInfo.ForeColor = Color.Blue;
            }
            else
            {
                lblClientInfo.Text = "请选择客户";
                lblClientInfo.ForeColor = Color.Gray;
            }
        }

        /// <summary>
        /// 填充表单数据
        /// 将传入的数据填充到各个控件中
        /// </summary>
        private void FillFormData()
        {
            // 客户单价编号（只读字段）
            txtClientPriceCode.Text = !string.IsNullOrEmpty(ClientPriceCode) ? ClientPriceCode : "";
            
            // 客户名称
            txtClient.Text = !string.IsNullOrEmpty(ClientName) ? ClientName : "";
            
            // 产品编码
            txtProductCode.Text = !string.IsNullOrEmpty(ProductCode) ? ProductCode : "";
            
            // 产品名称
            txtProduct.Text = !string.IsNullOrEmpty(ProductName) ? ProductName : "";
            
            // 产品规格型号
            txtProductSpec.Text = !string.IsNullOrEmpty(Specification) ? Specification : "";
            
            // 产品单价（格式化显示）
            if (!string.IsNullOrEmpty(Price) && double.TryParse(Price, out double priceValue))
            {
                txtProductPrice.Text = priceValue.ToString("F2");
            }
            else
            {
                txtProductPrice.Text = "0.00";
            }
            
            // 产品数量（格式化显示）
            if (!string.IsNullOrEmpty(Quantity) && int.TryParse(Quantity, out int quantityValue))
            {
                txtProductQuantity.Text = quantityValue.ToString();
            }
            else
            {
                txtProductQuantity.Text = "0";
            }
            
            // 总金额（格式化显示）
            if (!string.IsNullOrEmpty(TotalAmount) && double.TryParse(TotalAmount, out double totalAmountValue))
            {
                txtTotalAmount.Text = totalAmountValue.ToString("F2");
            }
            else
            {
                txtTotalAmount.Text = "0.00";
            }
            
            // 备注信息
            txtRemark.Text = !string.IsNullOrEmpty(Remark) ? Remark : "";
            
            // 设置创建日期
            SetCreateDate();
        }

        /// <summary>
        /// 设置创建日期
        /// </summary>
        private void SetCreateDate()
        {
            if (!string.IsNullOrEmpty(ClientPriceCode))
            {
                // 如果有客户单价编号，说明是修改现有记录，使用当前日期
                dateCreateDate.Value = DateTime.Now;
            }
            else
            {
                // 如果没有客户单价编号，说明是新增记录，使用当前日期
                dateCreateDate.Value = DateTime.Now;
            }
        }

        /// <summary>
        /// 如果需要，加载客户ID
        /// </summary>
        private async Task LoadClientIdIfNeeded()
        {
            if (!string.IsNullOrWhiteSpace(txtClient.Text) && ClientId == 0)
            {
                ClientId = await GetClientIdByNameAsync(txtClient.Text.Trim());
                if (ClientId > 0)
                {
                    txtClient.Tag = ClientId;
                }
            }
        }

        #region 事件处理方法

        /// <summary>
        /// 产品数量变化事件，自动计算总金额
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void TxtProductQuantity_TextChanged(object sender, EventArgs e)
        {
            CalculateTotalAmount();
        }

        /// <summary>
        /// 产品单价变化事件，自动计算总金额
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void TxtProductPrice_TextChanged(object sender, EventArgs e)
        {
            CalculateTotalAmount();
        }

        /// <summary>
        /// 客户名称变化事件，当客户名称清空时，同时清空客户信息显示标签
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void TxtClient_TextChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtClient.Text))
            {
                lblClientInfo.Text = "请选择客户";
                lblClientInfo.ForeColor = Color.Gray;
            }
        }

        #endregion

        #region 计算功能

        /// <summary>
        /// 自动计算总金额
        /// 根据产品单价和数量自动计算总金额
        /// </summary>
        private void CalculateTotalAmount()
        {
            try
            {
                decimal price = 0;
                decimal quantity = 0;
                decimal totalAmount = 0;

                // 尝试将产品单价和数量转换为小数
                if (!string.IsNullOrEmpty(txtProductPrice.Text) && decimal.TryParse(txtProductPrice.Text, out price) &&
                    !string.IsNullOrEmpty(txtProductQuantity.Text) && decimal.TryParse(txtProductQuantity.Text, out quantity))
                {
                    totalAmount = price * quantity;
                    txtTotalAmount.Text = totalAmount.ToString("F2");
                    
                    // 记录计算过程（可选，用于调试）
                    Console.WriteLine($"总金额计算: {price} × {quantity} = {totalAmount}");
                }
                else
                {
                    txtTotalAmount.Text = "0.00";
                    Console.WriteLine("总金额计算失败：单价或数量格式不正确");
                }
            }
            catch (Exception ex)
            {
                txtTotalAmount.Text = "0.00";
                Console.WriteLine($"总金额计算出错: {ex.Message}");
            }
        }

        #endregion

        #region 选择功能

        /// <summary>
        /// 客户选择按钮点击事件
        /// 打开客户选择窗体并获取选中的客户信息
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void BtnSelectClient_Click(object sender, EventArgs e)
        {
            try
            {
                // 打开客户选择窗体
                Client client = new Client();
                if (client.ShowDialog() == DialogResult.OK && client.SelectedClient != null)
                {
                    var selectedClient = client.SelectedClient;
                    // 更新客户名称显示
                    txtClient.Text = selectedClient.ClientName;
                    
                    // 更新客户名称属性
                    ClientName = selectedClient.ClientName;
                    // 缓存 ClientId
                    ClientId = selectedClient.ClientId;
                    txtClient.Tag = ClientId;
                    // 更新标签
                    lblClientInfo.Text = $"客户编码：{selectedClient.ClientCode} | 类型：{selectedClient.CTypeName} | 联系人：{selectedClient.ClientContact} | 电话：{selectedClient.ClientTel}";
                    lblClientInfo.ForeColor = Color.Green;
                    
                    // 显示选择成功提示，包含更多客户信息
                    string clientInfo = $"客户选择成功！\n\n" +
                                      $"客户名称：{selectedClient.ClientName}\n" +
                                      $"客户编码：{selectedClient.ClientCode}\n" +
                                      $"提示：客户已更改，请重新选择产品和填写相关信息。";
                    
                    MessageBox.Show(clientInfo, "客户选择成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    
                    // 记录日志（可选）
                    Console.WriteLine($"客户选择更新：{selectedClient.ClientName} - {selectedClient.ClientCode}");
                    
                    // 将焦点设置到产品选择按钮，引导用户下一步操作
                    btnSelectProduct.Focus();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择客户时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 产品选择按钮点击事件
        /// 打开产品选择窗体并获取选中的产品信息
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void BtnSelectProduct_Click(object sender, EventArgs e)
        {
            try
            {
                // 打开产品选择窗体
                SelectProduct selectProduct = new SelectProduct();
                if (selectProduct.ShowDialog() == DialogResult.OK && selectProduct.SelectedProduct != null)
                {
                    var selectedProduct = selectProduct.SelectedProduct;
                    
                    // 更新产品相关信息显示
                    txtProduct.Text = selectedProduct.ProductName;
                    txtProductCode.Text = selectedProduct.ProductCode;
                    txtProductSpec.Text = selectedProduct.Specification;
                    
                    // 更新产品相关属性
                    ProductName = selectedProduct.ProductName;
                    ProductCode = selectedProduct.ProductCode;
                    Specification = selectedProduct.Specification;
                    
                    // 显示选择成功提示
                    MessageBox.Show($"已选择产品：{selectedProduct.ProductName}\n产品编码：{selectedProduct.ProductCode}\n规格型号：{selectedProduct.Specification}", 
                        "产品选择", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    
                    // 记录日志（可选）
                    Console.WriteLine($"产品选择更新：{selectedProduct.ProductName} - {selectedProduct.ProductCode}");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择产品时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region 验证功能

        /// <summary>
        /// 验证反填后的数据完整性
        /// 检查关键字段是否已正确反填
        /// </summary>
        private void ValidateFilledData()
        {
            try
            {
                // 检查关键字段是否已正确反填
                bool hasClientPriceCode = !string.IsNullOrEmpty(txtClientPriceCode.Text.Trim());
                bool hasClientName = !string.IsNullOrEmpty(txtClient.Text.Trim());
                bool hasProductCode = !string.IsNullOrEmpty(txtProductCode.Text.Trim());
                bool hasProductName = !string.IsNullOrEmpty(txtProduct.Text.Trim());
                
                // 记录验证结果（可选，用于调试）
                Console.WriteLine($"数据反填验证结果：");
                Console.WriteLine($"  客户单价编号: {hasClientPriceCode} - {txtClientPriceCode.Text.Trim()}");
                Console.WriteLine($"  客户名称: {hasClientName} - {txtClient.Text.Trim()}");
                Console.WriteLine($"  产品编码: {hasProductCode} - {txtProductCode.Text.Trim()}");
                Console.WriteLine($"  产品名称: {hasProductName} - {txtProduct.Text.Trim()}");
                Console.WriteLine($"  产品规格: {txtProductSpec.Text.Trim()}");
                Console.WriteLine($"  单价: {txtProductPrice.Text.Trim()}");
                Console.WriteLine($"  数量: {txtProductQuantity.Text.Trim()}");
                Console.WriteLine($"  总金额: {txtTotalAmount.Text.Trim()}");
                Console.WriteLine($"  备注: {txtRemark.Text.Trim()}");
                
                // 如果有必要，可以在这里添加更严格的数据验证逻辑
                // 例如：检查数据格式、范围等
            }
            catch (Exception ex)
            {
                Console.WriteLine($"数据验证时出错: {ex.Message}");
            }
        }

        #endregion

        #region 更新功能

        /// <summary>
        /// 修改客户单价按钮点击事件
        /// 验证输入数据并调用API更新客户单价记录
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private async void btnUpdateClientPrice_Click(object sender, EventArgs e)
        {
            try
            {
                // 验证并获取客户ID
                if (!await ValidateAndGetClientId())
                {
                    return;
                }

                // 验证输入数据
                if (!ValidateInputData())
                {
                    return;
                }

                // 准备要更新的数据
                var updateData = PrepareUpdateData();

                // 调用API更新客户单价
                await UpdateClientPriceToApi(updateData);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"调用API时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 验证并获取客户ID
        /// </summary>
        /// <returns>验证是否通过</returns>
        private async Task<bool> ValidateAndGetClientId()
        {
            if (ClientId == 0 && !string.IsNullOrWhiteSpace(txtClient.Text))
            {
                ClientId = await GetClientIdByNameAsync(txtClient.Text.Trim());
            }
            if (ClientId == 0)
            {
                MessageBox.Show("请先选择有效的客户", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        /// <summary>
        /// 验证输入数据
        /// </summary>
        /// <returns>验证是否通过</returns>
        private bool ValidateInputData()
        {
            // 基本校验，避免 Parse 抛异常
            if (!double.TryParse(txtProductPrice.Text.Trim(), out double priceValue))
            {
                MessageBox.Show("单价格式不正确", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            if (!int.TryParse(txtProductQuantity.Text.Trim(), out int quantityValue))
            {
                MessageBox.Show("数量必须为整数", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        /// <summary>
        /// 准备更新数据
        /// </summary>
        /// <returns>更新数据对象</returns>
        private object PrepareUpdateData()
        {
            // 准备要更新的数据（字段名与 Swagger 保持驼峰对齐）
            return new
            {
                clientPriceId = ClientPriceId,
                clientPriceCode = txtClientPriceCode.Text.Trim(),
                clientId = ClientId,
                productCode = txtProductCode.Text.Trim(),
                price = double.Parse(txtProductPrice.Text.Trim()),
                number = int.Parse(txtProductQuantity.Text.Trim()),
                totalAmount = double.TryParse(txtTotalAmount.Text.Trim(), out double totalValue) ? totalValue : double.Parse(txtProductPrice.Text.Trim()) * int.Parse(txtProductQuantity.Text.Trim()),
                clientPriceRemark = txtRemark.Text.Trim()
            };
        }

        /// <summary>
        /// 调用API更新客户单价
        /// </summary>
        /// <param name="updateData">更新数据</param>
        private async Task UpdateClientPriceToApi(object updateData)
        {
            // 转换为JSON
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(updateData);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var response = await httpClient.PostAsync(baseUrl, content);
            var responseContent = await response.Content.ReadAsStringAsync();
            
            if (response.IsSuccessStatusCode)
            {
                var jo = JObject.Parse(string.IsNullOrWhiteSpace(responseContent) ? "{}" : responseContent);
                int code = (int?)(jo["code"]) ?? 0;
                string msg = (string)(jo["msg"]) ?? string.Empty;
                if (code == 200)
                {
                    MessageBox.Show("修改成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.DialogResult = DialogResult.OK;
                    this.Close();
                }
                else
                {
                    MessageBox.Show($"修改失败: {msg}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show($"修改失败：{response.StatusCode}\n{responseContent}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion
    }
}
